﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Windows.Storage;

namespace EveryBookies.Common
{
    public class LocalData : ILocalData
    {
        public const string DataSaveLocal = "DataSaveLocal";

        /// <summary>
        ///     Save Data To Local
        /// </summary>;
        public async void SaveData<T>(T data, string fileName)
        {
            string convert = await JsonConvert.SerializeObjectAsync(data);
            WriteData(fileName, convert);
        }

        async void WriteData(string fileName, string content)
        {
            byte[] data = Encoding.UTF8.GetBytes(content);

            StorageFolder folder = ApplicationData.Current.LocalFolder;
            StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

            using (Stream s = await file.OpenStreamForWriteAsync())
            {
                await s.WriteAsync(data, 0, data.Length);
            }
        }

        public async void DeleteDataSave<T>(string fileName)
        {
            if (await FileExists<T>(fileName))
            {
                StorageFolder folder = ApplicationData.Current.LocalFolder;

                try
                {
                    StorageFile file = await folder.GetFileAsync(fileName);
                    folder.DeleteAsync();
                }
                catch (Exception ex)
                {
                    
                }
            }
        }
        /// <summary>
        ///     Load Data From Local
        /// </summary>
        public async Task<T> LoadData<T>(string fileName)
        {
            T ret = default(T);
            var getData = await ReadData(fileName);

            if (getData != null)
            {
                ret = await JsonConvert.DeserializeObjectAsync<T>(getData);
            }
            return ret;
        }
        async Task<string> ReadData(string fileName)
        {
            byte[] data;
            StorageFolder folder = ApplicationData.Current.LocalFolder;
            
            try
            {
                StorageFile file = await folder.GetFileAsync(fileName);
                using (Stream s = await file.OpenStreamForReadAsync())
                {
                    data = new byte[s.Length];
                    await s.ReadAsync(data, 0, (int)s.Length);
                    return Encoding.UTF8.GetString(data, 0, data.Length);
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        /// <summary>
        ///     Check File Exists
        /// </summary>
        public async Task<bool> FileExists<T>(string fileName)
        {

            StorageFolder folder = ApplicationData.Current.LocalFolder;
            try
            {
                StorageFile file = await folder.GetFileAsync(fileName);
                if (file != null)
                    return true;
            }
            catch (Exception ex)
            {
                return false;
            }
            return false;
        }

        /// <summary>
        ///     Delete Data
        /// </summary>
        public bool DeleteData()
        {
            bool flag = false;
            var data = ApplicationData.Current.LocalSettings.Values;
            try
            {
                data.Clear();
                flag = true;
            }
            catch
            {
            }
            return flag;
        }

        /// <summary>
        ///  Delete a File
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns>True - success, False - failed</returns>
        public async Task<bool> DeleteFileAsync(string fileName)
        {
            bool flag = true;
            try
            {
                StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
                if (file != null)
                {
                    await file.DeleteAsync();
                }
            }
            catch (FileNotFoundException)
            {
                flag = false;
            }
            return flag;
        }


        /// <summary>
        ///     Serialize data to xml
        /// </summary>
        public string Serialize(object obj)
        {
            using (var sw = new StringWriter())
            {
                var serializer = new XmlSerializer(obj.GetType());
                serializer.Serialize(sw, obj);
                return sw.ToString();
            }
        }

        /// <summary>
        ///     Deserialize xml to data
        /// </summary>
        public T Deserialize<T>(string xml)
        {
            using (var sw = new StringReader(xml))
            {
                var serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(sw);
            }
        }
    }
}
